package dao

import (
	"fmt"
	"strconv"
	models "yuanaiproblem/dao/model" // 导入题目相关模型
	"yuanaiproblem/migrations/db"    // 导入数据库连接
	"yuanaiproblem/models/dto"       // 导入数据传输对象
)

// GetAllQuestionsByAdmin 分页查询所有题目
// 入参：页码、每页条数；
// 返回：分页数据和错误
func GetAllQuestionsByAdmin(page, pageSize int) (map[string]interface{}, error) {
	// 分页参数校验与默认值处理
	if page < 1 {
		page = 1 // 页码默认值为1
	}
	if pageSize < 1 || pageSize > 100 {
		pageSize = 10 // 页大小默认值为10，最大限制100条
	}

	var questions []models.Question // 存放查询到的题目
	var total int64                 // 总记录数
	offset := (page - 1) * pageSize // 计算分页偏移量（经过参数校验后，此处不会出现负数）

	// 查询总条数（排除软删除数据）
	if err := db.DB.Model(&models.Question{}).
		Where("deleted_at IS NULL"). // 新增：只查未删除的题目
		Count(&total).Error; err != nil {
		return nil, err
	}

	// 分页查询题目，按ID倒序（排除软删除数据）
	query := db.DB.Model(&models.Question{}).
		Where("deleted_at IS NULL"). // 新增：排除已删除题目
		Order("id DESC").
		Offset(offset).
		Limit(pageSize)

	if err := query.Find(&questions).Error; err != nil {
		return nil, err
	}

	// 打印调试信息（可选，方便排查问题）
	fmt.Printf("有效分页参数：page=%d, pageSize=%d, offset=%d, 总记录数=%d\n",
		page, pageSize, offset, total)

	// 组装返回结果
	result := map[string]interface{}{
		"total":     total,
		"page":      page,
		"page_size": pageSize,
		"questions": questions,
	}
	return result, nil
}

// AdminGetQuestionByID 查询单个题目
// 入参：题目ID；
// 返回：题目详情和错误
func AdminGetQuestionByID(id int) (*models.Question, error) {
	var question models.Question // 存放查询到的题目

	// 根据ID查询题目
	result := db.DB.First(&question, id)
	if result.Error != nil {
		return nil, result.Error
	}
	return &question, nil
}

// GetUserStats 获取用户维度统计
// 入参：用户ID；
// 返回：用户统计数据和错误
func GetUserStats(userID string) (*dto.UserStatsResponse, error) {
	var user models.User // 存放用户信息
	// 查询用户基本信息（不排除软删除）
	if err := db.DB.
		Where("id = ? AND deleted_at IS NULL", userID).
		First(&user).Error; err != nil {
		return nil, fmt.Errorf("查询用户信息失败: %w", err)
	}
	// 初始化统计响应结构
	response := dto.UserStatsResponse{
		UserID:            user.ID,
		Username:          user.Username,
		QuestionTypeStats: make(map[string]int64),
		ActivityHours:     make(map[int]int64),
		ActivityDays:      make(map[string]int64),
	}
	// 统计用户创建的题目和试卷数量（不排除软删除）
	if err := db.DB.Model(&models.Question{}).
		Where("user_id = ?", userID).
		Count(&response.QuestionCount).Error; err != nil {
		return nil, fmt.Errorf("统计用户题目数量失败: %w", err)
	}
	if err := db.DB.Model(&models.Paper{}).
		Where("creator_id = ?", userID).
		Count(&response.PaperCount).Error; err != nil {
		return nil, fmt.Errorf("统计用户试卷数量失败: %w", err)
	}

	// 按题目类型统计指定用户创建的题目数量
	var questionTypeStats []struct {
		QuestionType string `gorm:"column:question_type"`
		Count        int64  `gorm:"column:count"`
	}
	if err := db.DB.Model(&models.Question{}).
		Where("user_id = ?", userID).
		Select("question_type, count(*) as count").
		Group("question_type").
		Scan(&questionTypeStats).Error; err != nil {
		return nil, fmt.Errorf("按类型统计题目失败: %w", err)
	}
	for _, item := range questionTypeStats {
		response.QuestionTypeStats[item.QuestionType] = item.Count
	}

	// 统计指定用户在一天中每个小时创建的题目数量
	var hourlyActivity []struct {
		Hour  int   `gorm:"column:hour"`
		Count int64 `gorm:"column:count"`
	}
	if err := db.DB.Model(&models.Question{}).
		Where("user_id = ? AND deleted_at IS NULL", userID).
		Select("CAST(strftime('%H', created_at) AS INTEGER) as hour, count(*) as count"). // SQLite提取小时并转为整数
		Group("hour").
		Scan(&hourlyActivity).Error; err != nil {
		return nil, fmt.Errorf("统计小时活动失败: %w", err)
	}
	for _, item := range hourlyActivity {
		response.ActivityHours[item.Hour] = item.Count
	}

	// 按日期统计指定用户创建的题目数量
	var dailyActivity []struct {
		Day   string `gorm:"column:day"`
		Count int64  `gorm:"column:count"`
	}
	if err := db.DB.Model(&models.Question{}).
		Where("user_id = ?", userID).
		Select("date(created_at) as day, count(*) as count"). // SQLite日期格式化
		Group("day").
		Order("day"). // 按日期排序
		Scan(&dailyActivity).Error; err != nil {
		return nil, fmt.Errorf("统计每日活动失败: %w", err)
	}
	for _, item := range dailyActivity {
		response.ActivityDays[item.Day] = item.Count
	}
	return &response, nil
}

// GetSystemStats 获取系统维度统计（仅适配 SQLite）
// 入参：无
// 返回：系统统计数据和可能的错误
func GetSystemStats() (*dto.SystemStatsResponse, error) {
	// 初始化响应结构体
	response := &dto.SystemStatsResponse{
		LanguageStats:  make(map[string]int64),
		AIModelStats:   make(map[string]int64),
		PaperSizeStats: make(map[string]int64),
		DailyActivity:  make(map[string]int64),
		WeeklyActivity: make(map[string]int64),
	}

	// 统计总用户、题目、试卷数量（不排除软删除数据）
	if err := db.DB.Model(&models.User{}).
		Count(&response.TotalUsers).Error; err != nil {
		return nil, fmt.Errorf("统计总用户数失败: %w", err)
	}
	if err := db.DB.Model(&models.Question{}).
		Count(&response.TotalQuestions).Error; err != nil {
		return nil, fmt.Errorf("统计总题目数失败: %w", err)
	}
	if err := db.DB.Model(&models.Paper{}).
		Count(&response.TotalPapers).Error; err != nil {
		return nil, fmt.Errorf("统计总试卷数失败: %w", err)
	}

	// 按语言类型统计题目
	var languageStats []struct {
		Language string `gorm:"column:language"`
		Count    int64  `gorm:"column:count"`
	}
	if err := db.DB.Model(&models.Question{}).
		Select("language, COUNT(*) as count").
		Group("language").
		Scan(&languageStats).Error; err != nil {
		return nil, fmt.Errorf("按语言统计题目失败: %w", err)
	}
	for _, item := range languageStats {
		response.LanguageStats[item.Language] = item.Count
	}

	// 按AI模型统计题目
	var aiModelStats []struct {
		AIModel string `gorm:"column:ai_model"`
		Count   int64  `gorm:"column:count"`
	}
	if err := db.DB.Model(&models.Question{}).
		Select("ai_model, COUNT(*) as count").
		Group("ai_model").
		Scan(&aiModelStats).Error; err != nil {
		return nil, fmt.Errorf("按AI模型统计题目失败: %w", err)
	}
	for _, item := range aiModelStats {
		response.AIModelStats[item.AIModel] = item.Count
	}

	// 按试卷大小（题目数量）统计
	var paperSizeStats []struct {
		Size    int64 `gorm:"column:size"`
		PaperID int32 `gorm:"column:paper_id"`
	}
	// 先查询每份试卷的题目数量（排除软删除的试卷和题目）
	if err := db.DB.Model(&models.PaperQuestion{}).
		Joins("JOIN papers ON papers.id = paper_questions.paper_id AND papers.deleted_at IS NULL").
		Joins("JOIN questions ON questions.id = paper_questions.question_id AND questions.deleted_at IS NULL").
		Select("paper_questions.paper_id, COUNT(paper_questions.question_id) as size").
		Group("paper_questions.paper_id").
		Scan(&paperSizeStats).Error; err != nil {
		return nil, fmt.Errorf("统计试卷题目数量失败: %w", err)
	}
	// 按题目数量分组统计试卷数
	sizeCountMap := make(map[int64]int64)
	for _, item := range paperSizeStats {
		sizeCountMap[item.Size]++
	}
	// 转换为字符串键
	for size, count := range sizeCountMap {
		response.PaperSizeStats[strconv.FormatInt(size, 10)] = count
	}

	// 按日期统计每日活动
	var dailyActivity []struct {
		Day   string `gorm:"column:day"`
		Count int64  `gorm:"column:count"`
	}
	if err := db.DB.Model(&models.Question{}).
		Where("deleted_at IS NULL").
		Select("date(created_at) as day, COUNT(*) as count"). // SQLite 日期格式化：YYYY-MM-DD
		Group("day").
		Order("day"). // 按日期排序
		Scan(&dailyActivity).Error; err != nil {
		return nil, fmt.Errorf("统计每日活动失败: %w", err)
	}
	for _, item := range dailyActivity {
		response.DailyActivity[item.Day] = item.Count
	}

	// 按周统计每周活动
	var weeklyActivity []struct {
		YearWeek string `gorm:"column:year_week"`
		Count    int64  `gorm:"column:count"`
	}
	// SQLite 中用 strftime 提取年份和周数（%Y-年份，%W-周数，0-53）
	if err := db.DB.Model(&models.Question{}).
		Where("deleted_at IS NULL").
		Select("printf('%s-%02d', strftime('%Y', created_at), strftime('%W', created_at)) as year_week, COUNT(*) as count").
		Group("year_week").
		Order("year_week"). // 按周排序
		Scan(&weeklyActivity).Error; err != nil {
		return nil, fmt.Errorf("统计每周活动失败: %w", err)
	}
	for _, item := range weeklyActivity {
		response.WeeklyActivity[item.YearWeek] = item.Count
	}

	return response, nil
}
